﻿// TODO: Needs to be fixed for new ImageData setup.

//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using TLD_Vision.filters;
//using System.Drawing;

//namespace TLD_Vision.OCR
//{
//    struct Vector
//    {
//        public int x;
//        public int y;
//        double length;

//        public Vector(int x, int y)
//        {
//            this.x = x;
//            this.y = y;
//            length = 0;
//        }

//        public double Length() {
//            if (length == 0) {
//                length = Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2));
//            }
//            return length;
//        }
//    }
    
//    public class ShapeContexts
//    {
//        private int numRadialBins, numDistanceBins;
//        private int numContourPoints;
//        private Random rand;
//        double[,] sourceHist;

//        public ShapeContexts(int numContourPoints, int numRadialBins, int numDistanceBins, Image source)
//        {
//            this.numContourPoints = numContourPoints;
//            this.numRadialBins = numRadialBins;
//            this.numDistanceBins = numDistanceBins;
//            rand = new Random();

//            Image prewittNMS = source.ApplyPrewittAndNMS();
//            Image threshold = prewittNMS.manipulatePixels(filters.Filters.ApplyThreshold(127));
//            sourceHist = CreateHistogram(threshold.Height / 2, new Vector(threshold.Width / 2, threshold.Height / 2), GetContourPoints(source));
//        }

//        private Vector[] GetContourPoints(Image img)
//        {
//            Vector[] contourPoints = new Vector[numContourPoints];
//            int width = img.Width, height = img.Height;
//            List<Vector> allContourPoints = new List<Vector>();

//            unsafe
//            {
//                uint* pPixel = (uint*)img.GetDataPointer();
//                for (int i = 0 ; i < width * height ; ++i)
//                {
//                    if ((pPixel[i] & 0x00FFFFFF) > 0)
//                    {
//                        allContourPoints.Add(new Vector(i % width, i / width));
//                    }
//                }
//                img.Unlock();
//            }

//            for (int i = 0; i < Math.Min(allContourPoints.Count, numContourPoints); ++i)
//            {
//                int rndIndex = rand.Next(allContourPoints.Count);
//                contourPoints[i] = allContourPoints[rndIndex];
//                allContourPoints.RemoveAt(rndIndex);
//            }

//            return contourPoints;
//        }

//        private double[,] CreateHistogram(int maxR, Vector origin, Vector[] contourPoints)
//        {
//            double[,] histogram = new double[numRadialBins, numDistanceBins];
//            double logStep = Math.Log10(maxR+1) / numDistanceBins;
//            double radialStep = 2 * Math.PI / numRadialBins;
//            double[] logThreshold = new double[numDistanceBins +1];

//            for (int i = 0; i <= numDistanceBins; ++i)
//            {
//                logThreshold[i] = i * logStep;
//            }

//            foreach (Vector point in contourPoints) {
//                float dy, dx;
//                dx = origin.x - point.x;
//                dy = origin.y - point.y;

//                double dist = Math.Log10(Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)));
//                double theta = dx > 0 ? Math.Atan(dy / dx) : 0;
//                if (dx == 0 && dy == 0)
//                {
//                    continue;
//                }

//                if (dy < 0)
//                {
//                    if (dx < 0)
//                    {
//                        theta += Math.PI;
//                    }
//                    else if (dx > 0)
//                    {
//                        theta = 1.5 * Math.PI + (0.5 * Math.PI + theta);
//                    }
//                    else
//                    {
//                        theta = 1.5 * Math.PI;
//                    }
//                }
//                else if (dx < 0)
//                {
//                    theta = 0.5 * Math.PI + (0.5 * Math.PI + theta);
//                }
//                else
//                {
//                    theta = 0.5 * Math.PI;
//                }

//                int destDistanceBin = 0;
//                for (int i = 0; i < numDistanceBins; ++i)
//                {
//                    if (dist < logThreshold[i+1])
//                    {
//                        destDistanceBin = i;
//                        break;
//                    }
//                }

//                histogram[(int)(theta / radialStep), destDistanceBin]++;
//            }

//            return histogram;
//        }

//        private double CalculateCost(double[,] originHistogram, double[,] templateHistogram)
//        {
//            double cost = 0;
//            for (int r = 0; r < numRadialBins; ++r)
//            {
//                for (int d = 0; d < numDistanceBins; ++d)
//                {
//                    if (Math.Abs((originHistogram[r, d] - templateHistogram[r, d])) > 0)
//                    {
//                        cost += Math.Pow(originHistogram[r, d] - templateHistogram[r, d], 2) / (originHistogram[r, d] + templateHistogram[r, d]);
//                    }
//                }
//            }

//            return cost / 2;
//        }

//        public Image DrawContourPoints(Image img)
//        {
//            Image prewittNMS = img.ApplyPrewittAndNMS();
//            Image threshold = prewittNMS.manipulatePixels(filters.Filters.ApplyThreshold(127));

//            Vector[] contourPoints = GetContourPoints(threshold);
            

//            Bitmap bmp = new Bitmap(threshold.Width, threshold.Height);
//            Graphics g = Graphics.FromImage(bmp);
//            g.FillRectangle(Brushes.White, 0, 0, threshold.Width, threshold.Height);
//            double[,] hist = CreateHistogram(threshold.Height / 2, new Vector(threshold.Width / 2, threshold.Height / 2), contourPoints);
            
//            Point center = new Point(threshold.Width / 2, threshold.Height / 2);
//            double rStep = Math.Log10(threshold.Height / 2) / numDistanceBins;
//            bool first = true;
//            for (int i = numDistanceBins; i >= 0; --i)
//            {
//                double radius = Math.Pow(10, rStep * i);
//                g.DrawEllipse(first ? Pens.Green : Pens.Black, (int)(center.X - radius), (int)(center.Y - radius), (int)(2 * radius), (int)(2 * radius));
//                first = false;
//            }

//            for (int i = 0; i < contourPoints.Length; ++i)
//            {
//                bmp.SetPixel(contourPoints[i].x, contourPoints[i].y, System.Drawing.Color.Red);
//            }

//            for (int i = 0; i < numRadialBins; ++i)
//            {
//                System.Diagnostics.Debug.WriteLine(String.Format("{0}, {1}, {2}, {3}, {4}", hist[i, 0], hist[i, 1], hist[i, 2], hist[i, 3], hist[i, 4]));
//            }

//            return new Image(bmp);
//        }

//        public double GetCost(Image template)
//        {
//            Image prewittNMS = template.ApplyPrewittAndNMS();
//            Image threshold = prewittNMS.manipulatePixels(filters.Filters.ApplyThreshold(127));
//            Vector[] contourPoints = GetContourPoints(threshold);
//            Vector centre = new Vector(threshold.Width / 2, threshold.Height / 2);

//            return CalculateCost(sourceHist, CreateHistogram((int)Math.Sqrt(centre.x * centre.x + centre.y * centre.y), centre, contourPoints));
//        }
//    }
//}
